#include <stdio.h>

#include <unistd.h>

#include "ohos_init.h"
#include "cmsis_os2.h"

#include <unistd.h>
#include "hi_wifi_api.h"
//#include "wifi_sta.h"
#include "lwip/ip_addr.h"
#include "lwip/netifapi.h"

#include "lwip/sockets.h"

#include "MQTTPacket.h"
#include "transport.h"
// #include "traffic_light.h"


#include <stdio.h>
#include <string.h>
#include <unistd.h>

#include "ohos_init.h"
#include "cmsis_os2.h"
#include "lwip/netifapi.h"
#include "lwip/api_shell.h"
#include "wifi_utils.h"
#include "mqtt_utils.h"
#include <hi_at.h>

#define HOST_ADDR "192.168.24.175"
#define     SSID        "Rowe Ultra"
#define     PASSWORD    "lyhqq010922"





char payload[200];
char payload1[200];
char payload2[200];
char payload3[200];
int toStop = 0;

int mqtt_connect(void)
{
	MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
	int rc = 0;
	int mysock = 0;
	unsigned char buf[200];
	int buflen = sizeof(buf);
	int msgid = 1;
	MQTTString topicString = MQTTString_initializer;
	int req_qos = 0;
	// char payload[200] = "you are successful finally！！！ ૮ (˶ᵔ ᵕ ᵔ˶)ა"; 	//发送数据
	int payloadlen = strlen(payload);
	int payloadlen1 = strlen(payload1);
	int payloadlen2 = strlen(payload2);
	int payloadlen3 = strlen(payload3);
	int len = 0;
	char *host = HOST_ADDR;  //MQTT服务器的IP地址 
	int port = 1883;

	mysock = transport_open(host, port);
	if (mysock < 0)
		return mysock;

	printf("Sending to hostname %s port %d\n", host, port);

	data.clientID.cstring = "hi3861";  //修改成自己名称，
	data.keepAliveInterval = 20;	//心跳时间
	data.cleansession = 1;
	data.username.cstring = "hi3861";
	data.password.cstring = "1024";

	len = MQTTSerialize_connect(buf, buflen, &data);
	rc = transport_sendPacketBuffer(mysock, buf, len);

	/* wait for connack */
	if (MQTTPacket_read(buf, buflen, transport_getdata) == CONNACK)
	{
		unsigned char sessionPresent, connack_rc;

		if (MQTTDeserialize_connack(&sessionPresent, &connack_rc, buf, buflen) != 1 || connack_rc != 0)
		{
			printf("Unable to connect, return code %d\n", connack_rc);
			goto exit;
		}
	}
	else
		goto exit;

	/* subscribe 订阅主题 */
	topicString.cstring = "subtopic";
	len = MQTTSerialize_subscribe(buf, buflen, 0, msgid, 1, &topicString, &req_qos);		//打包橙订阅主题包保存在buf中
	rc = transport_sendPacketBuffer(mysock, buf, len);				//客户端发送订阅主题至服务器
	if (MQTTPacket_read(buf, buflen, transport_getdata) == SUBACK) /* 等待服务器返回订阅主题ACK响应包 */
	{
		unsigned short submsgid;
		int subcount;
		int granted_qos;

		rc = MQTTDeserialize_suback(&submsgid, 1, &subcount, &granted_qos, buf, buflen);
		if (granted_qos != 0)
		{
			printf("granted qos != 0, %d\n", granted_qos);
			goto exit;
		}
	}
	else
		goto exit;

	/* loop getting msgs on subscribed topic */
	
	while (!toStop)
	{
		/* transport_getdata() has a built-in 1 second timeout,
		your mileage will vary */
		if (MQTTPacket_read(buf, buflen, transport_getdata) == PUBLISH)
		{
			unsigned char dup;
			int qos;
			unsigned char retained;
			unsigned short msgid;
			int payloadlen_in;
			unsigned char *payload_in;
			int rc;
			MQTTString receivedTopic;

			// 
			rc = MQTTDeserialize_publish(&dup, &qos, &retained, &msgid, &receivedTopic,
										 &payload_in, &payloadlen_in, buf, buflen);
			printf("message arrived %d,%s\n", payloadlen_in, payload_in);
			rc = rc;
			
		}
		topicString.cstring = "publish2";   //发布设置主题
        printf("bodytemp:%s\n", payload);
		payloadlen=strlen(payload);
		len = MQTTSerialize_publish(buf, buflen, 0, 0, 0, 0, topicString, (unsigned char *)payload, payloadlen);
		rc = transport_sendPacketBuffer(mysock, buf, len);
        
		topicString.cstring = "publish7";   //发布设置主题
        printf("latitude:%s\n", payload1);
		payloadlen1=strlen(payload1);
		len = MQTTSerialize_publish(buf, buflen, 0, 0, 0, 0, topicString, (unsigned char *)payload1, payloadlen1);
		rc = transport_sendPacketBuffer(mysock, buf, len);
		
		topicString.cstring = "publish5";   //发布设置主题
        printf("longitude:%s\n", payload2);
		payloadlen2=strlen(payload2);
		len = MQTTSerialize_publish(buf, buflen, 0, 0, 0, 0, topicString, (unsigned char *)payload2, payloadlen2);
		rc = transport_sendPacketBuffer(mysock, buf, len);
		
		topicString.cstring = "publish6";   //发布设置主题
        printf("sp0:%s\n", payload3);
		payloadlen3=strlen(payload3);
		len = MQTTSerialize_publish(buf, buflen, 0, 0, 0, 0, topicString, (unsigned char *)payload3, payloadlen3);
		rc = transport_sendPacketBuffer(mysock, buf, len);

		usleep(100000);
	}

	printf("disconnecting\n");
	len = MQTTSerialize_disconnect(buf, buflen);
	rc = transport_sendPacketBuffer(mysock, buf, len);	//客户端发送发布主题包至服务器
exit:
	transport_close(mysock);

	rc = rc;

	return 0;
}

static void mqtt_test_thread(void *arg)
{
    
	(void)arg;
    connect_wifi(SSID, PASSWORD); //连接WIFI热点
    printf("begin mqtt  demo\n");

    mqtt_connect();//运行mqtt测试程序
}

//在函数中创建新线程
static void at_exe_mqtt_test_cmd(void)
{
    osThreadAttr_t attr;

    attr.name = "wifi_config_thread";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = 4096;
    attr.priority = 34;

    //在新线程中执行函数mqtt_test_thread
    if (osThreadNew((osThreadFunc_t)mqtt_test_thread, NULL, &attr) == NULL)
    {
        printf("[LedExample] Falied to create LedTask!\n");
    }

    // return HI_ERR_SUCCESS;
}
APP_FEATURE_INIT(at_exe_mqtt_test_cmd);